﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace INSTA.Concepts.HeritagePoly
{
    class Program
    {
        static void Main(string[] args)
        {
            // Commenter / décommenter les appels pour 
            // tester les méthodes.

            //Test_Poly_01();

            Test_Poly_02();
        }

        public static void Test_Poly_01()
        {
            // Pas de polymorphisme !
            // Type de déclaration  : Car
            // Type instancié       : Car    
            // Car c = new Car();
            //c.Accelerate();

            Console.WriteLine();

            // Pas de polymorphisme !
            // Type de déclaration  : Maserati
            // Type instancié       : Maserati    
            Maserati m = new Maserati();
            m.Accelerate();

            Console.WriteLine();

            // POLYMORPHISME !!!
            // Type de déclaration  : Classe de base Car
            // Type instancié       : Classe dérivée BMW
            Car x = new BMW();

            /* Ici, on appelle la méthode "Accelerate" (définie en 
             * tant que méthode virtuelle dans la classe Car, et redéfinie
             * dans la classe BMW)
             * 
             * C'est TOUJOURS sur le type instancié que l'appel de 
             * méthode va s'effectuer. 
             * Ici, c'est donc "BMW.Accelerate" qui va être appelée.
             */
            x.Accelerate();
        }


        public static void Test_Poly_02()
        {
            // On déclare un tableau dont chacune des cases
            // contient une variable de type Car.
            Car[] cars = new Car[3];

            cars[0] = new Clio();
            cars[1] = new BMW();
            cars[2] = new Maserati();

            foreach (Car theCar in cars)
            {
                theCar.Accelerate();
                
                // On teste si on peut caster la voiture 
                // en cours en Maserati..
                if (theCar is Maserati)
                {
                    // On caste la variable en cours en Maserati..
                    Maserati theMaserati = theCar as Maserati;

                    // Cette ligne est fonctionnellement équivalente
                    // à celle du dessus.
                    //Maserati theMaserati2 = (Maserati) theCar;
                    // Maintenant que l'on dispose d'une variable dont 
                    // le type de déclaration est "Maserati", on appelle 
                    // la méthode "InitTurbo", que seule les Maseratis
                    // possèdent.
                    theMaserati.InitTurbo();
                }
            }

        }
























    }
}
